using Microsoft.Practices.Unity;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using UniAspect.ContainerOverride;
using UniAspect.UnityCommon;

namespace UniAspect.UnitTests
{
    [TestFixture]
    public class ContainerOverrideExtension
    {
        [Test]
        public void OverrideByContainer()
        {
            var main = new UnityContainer();
            var oveeride1 = main.CreateOverride("1");
            oveeride1.RegisterType<ISomeInterface, Implementation1>();
            var override2 = main.CreateOverride("2");
            override2.RegisterType<ISomeInterface, Implementation2>();

            var complexClass = main.Resolve<ComplexClass>();
            Assert.That(complexClass.Dependency1.Interface,
                        Is.InstanceOfType(typeof(Implementation1)));

            Assert.That(complexClass.Dependency2.Interface,
                        Is.InstanceOfType(typeof(Implementation2)));
        }

        [Test]
        public void OverrideSigletonContainer()
        {
            var main = new UnityContainer();
            main.RegisterSingleton<ISomeInterface, Implementation2>();
            var oveeride1 = main.CreateOverride("1");
            oveeride1.RegisterSingleton<ISomeInterface, Implementation1>();

            var complexClass = main.Resolve<ComplexClass2>();
            Assert.That(complexClass.Dependency1.Interface,
                        Is.InstanceOfType(typeof(Implementation1)));

            Assert.That(complexClass.Dependency2.Interface,
                        Is.InstanceOfType(typeof(Implementation2)));
        }

        [Test]
        [ExpectedException(typeof(ResolutionFailedException))]
        public void RequestNonExistingOverride()
        {
            var main = new UnityContainer();
            main.RegisterSingleton<ISomeInterface, Implementation2>();
            var oveeride1 = main.CreateOverride("1");
            oveeride1.RegisterSingleton<ISomeInterface, Implementation1>();

            main.Resolve<ComplexClass>();
        }



        public class ComplexClass
        {
            [ContainerOverride(ContainerName = "1")]
            public SubClass1 Dependency1 { get; set; }

            [ContainerOverride(ContainerName = "2")]
            public SubClass2 Dependency2 { get; set; }            
        }

        public class ComplexClass2
        {
            [ContainerOverride(ContainerName = "1")]
            public SubClass1 Dependency1 { get; set; }

            [Dependency]
            public SubClass2 Dependency2 { get; set; }
        }

        public class BaseClass
        {
            [Dependency]
            public ISomeInterface Interface { get; set; }
        }


        public class SubClass1 : BaseClass
        {

        }

        public class SubClass2 : BaseClass
        {

        }

        public interface ISomeInterface
        {
        }

        public class Implementation1 : ISomeInterface
        {
            
        }

        public class Implementation2 : ISomeInterface
        {

        }
    }
}